package com.hm.cms.auto;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.hm.cms.auto.SystemEnvConfigProperties.RedisConfig;
import com.hm.cms.auto.SystemEnvConfigProperties.RedisConfig.RedisPool;
import com.hm.cms.service.AdvertService;
import com.hm.cms.service.ArticleService;
import com.hm.cms.service.BlacklistService;
import com.hm.cms.service.BoosSerice;
import com.hm.cms.service.ExtLinkService;
import com.hm.cms.service.TermTaxonomyService;
import com.hm.cms.service.TermTayRelationshipsService;
import com.hm.cms.service.TermsService;
import com.hm.cms.service.VisitIpStatisticsService;
import com.hm.common.redis.jedis.JedisFactory;
import com.hm.common.redis.jedis.su.JedisHandlerSupport;

import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.JedisPoolConfig;

/**
 * @author shishun.wang
 * @date 上午11:43:29 2017年9月27日
 * @version 1.0
 * @describe
 */
@Slf4j
@EnableAsync // 配置 @Async 异步生效
@Configuration
@EnableConfigurationProperties({ SystemEnvConfigProperties.class })
public class HmServerConfiguration {

	@Autowired
	private BeanFactory beanFactory;
	
	@Autowired
	private SystemEnvConfigProperties systemEnvConfigProperties;

	@Bean
	public TaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(10);
		executor.setKeepAliveSeconds(300);
		executor.setMaxPoolSize(15);
		executor.setQueueCapacity(25);
		return executor;
	}

	/**** provide rpc invoker interface *******/

	@Bean(name = AdvertService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter advertService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(AdvertService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(AdvertService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = ArticleService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter articleService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(ArticleService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(ArticleService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = BoosSerice.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter boosSerice() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(BoosSerice.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(BoosSerice.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = ExtLinkService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter extLinkService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(ExtLinkService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(ExtLinkService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = TermsService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter termsService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(TermsService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(TermsService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = TermTaxonomyService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter termTaxonomyService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(TermTaxonomyService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(TermTaxonomyService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = TermTayRelationshipsService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter termTayRelationshipsService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(TermTayRelationshipsService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(TermTayRelationshipsService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}

	@Bean(name = VisitIpStatisticsService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter visitIpStatisticsService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(VisitIpStatisticsService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(VisitIpStatisticsService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}
	
	@Bean(name = BlacklistService.HTTP_INVOKER_EXPORT_CONTEXT)
	public HttpInvokerServiceExporter blacklistService() {
		HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();
		httpInvokerServiceExporter.setServiceInterface(BlacklistService.class);
		httpInvokerServiceExporter.setService(beanFactory.getBean(BlacklistService.class));
		httpInvokerServiceExporter.afterPropertiesSet();
		return httpInvokerServiceExporter;
	}
	
	@Bean
	public JedisFactory jedisFactory() {
		RedisConfig redisConfig = systemEnvConfigProperties.getRedisConfig();
		JedisPoolConfig config = new JedisPoolConfig();
		{
			RedisPool pool = redisConfig.getPool();
			config.setMaxIdle(pool.getMaxIdle());// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8
			config.setMaxTotal(pool.getMaxTotal());
			config.setMaxWaitMillis(pool.getMaxWaitMillis());
			config.setTestOnBorrow(pool.isTestOnBorrow());
		}

		return new JedisFactory().build(config, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getPassword(),
				redisConfig.getTimeout());
	}

	@Bean
	public JedisHandlerSupport jedisHandler() {
		return new JedisHandlerSupport(jedisFactory());
	}
}
